package ro.dta.idbi.ui.sql;

import java.awt.Color;
import java.util.Hashtable;
import java.util.Map;

import ro.dta.idbi.interfaces.sql.ISqlColumn;
import ro.dta.idbi.interfaces.sql.ISqlForeignKey;

import com.mxgraph.model.mxCell;
import com.mxgraph.util.mxConstants;
import com.mxgraph.view.mxGraph;
import com.mxgraph.view.mxStylesheet;

/**
 * Sql graph class, used to display constructs of an SQL schema
 * 
 * @author Tudor Dobrila
 * 
 */
public class SqlGraph extends mxGraph {

	/**
	 * SqlGraph class constructor
	 */
	public SqlGraph() {
		super();
		setHtmlLabels(true);
		setCellsEditable(false);
		setCellsResizable(false);
		setCellsDeletable(false);
		setCellsCloneable(false);
		setAllowDanglingEdges(false);
		orderCells(false);
		setConnectableEdges(false);
		setDropEnabled(false);

		// Create style sheets
		final mxStylesheet stylesheet = getStylesheet();
		this.createStylesheets(stylesheet);
	}

	/**
	 * Create the style sheets used when displaying the schema
	 * 
	 * @param styleSheet
	 *            Style sheet where styles will be added
	 */
	private void createStylesheets(final mxStylesheet styleSheet) {
		mxConstants.VERTEX_SELECTION_COLOR = Color.BLACK;

		// Style for tables
		final Map<String, Object> style = new Hashtable<String, Object>();
		style.put(mxConstants.STYLE_SHAPE, mxConstants.SHAPE_RECTANGLE);
		style.put(mxConstants.STYLE_VERTICAL_ALIGN, mxConstants.ALIGN_TOP);
		style.put(mxConstants.STYLE_FONTSTYLE, mxConstants.FONT_BOLD);
		style.put(mxConstants.STYLE_OPACITY, 50);
		style.put(mxConstants.STYLE_FONTCOLOR, "#000000");
		style.put(mxConstants.STYLE_FONTSIZE, 13);
		styleSheet.putCellStyle("TABLE", style);

		// Style for columns
		final Map<String, Object> style2 = new Hashtable<String, Object>();
		style2.put(mxConstants.STYLE_SHAPE, mxConstants.SHAPE_RECTANGLE);
		style2.put(mxConstants.STYLE_ALIGN, mxConstants.ALIGN_LEFT);
		style2.put(mxConstants.STYLE_FONTSIZE, 13);
		styleSheet.putCellStyle("COLUMN", style2);

		// Style for primary keys
		final Map<String, Object> style3 = new Hashtable<String, Object>();
		style3.put(mxConstants.STYLE_SHAPE, mxConstants.SHAPE_RECTANGLE);
		style3.put(mxConstants.STYLE_ALIGN, mxConstants.ALIGN_LEFT);
		style3.put(mxConstants.STYLE_FONTSTYLE, mxConstants.FONT_UNDERLINE);
		style3.put(mxConstants.STYLE_FONTSIZE, 13);
		styleSheet.putCellStyle("PRIMARYKEY", style3);

		// Style for foreign edges
		final Map<String, Object> style4 = new Hashtable<String, Object>();
		style4.put(mxConstants.STYLE_DIRECTION, mxConstants.DIRECTION_EAST);
		style4.put(mxConstants.STYLE_EDGE, mxConstants.EDGESTYLE_ELBOW);
		style4.put(mxConstants.STYLE_ROUNDED, "true");
		style4.put(mxConstants.STYLE_ENDARROW, mxConstants.ARROW_BLOCK);
		style4.put(mxConstants.STYLE_FONTCOLOR, "#111111");
		style4.put(mxConstants.STYLE_LABEL_BACKGROUNDCOLOR, "#eeeeee");
		style4.put(mxConstants.STYLE_LABEL_BORDERCOLOR, "#111111");
		style4.put(mxConstants.STYLE_STROKECOLOR, "#333333");
		styleSheet.putCellStyle("FK_EDGE", style4);

		// Style for highlighted columns
		final Map<String, Object> style5 = new Hashtable<String, Object>();
		style5.put(mxConstants.STYLE_SHAPE, mxConstants.SHAPE_RECTANGLE);
		style5.put(mxConstants.STYLE_ALIGN, mxConstants.ALIGN_LEFT);
		style5.put(mxConstants.STYLE_FONTSIZE, 13);
		style5.put(mxConstants.STYLE_FILLCOLOR, "#f7da77");
		styleSheet.putCellStyle("SEL_COL", style5);

		final Map<String, Object> style6 = new Hashtable<String, Object>();
		style6.put(mxConstants.STYLE_SHAPE, mxConstants.SHAPE_RECTANGLE);
		style6.put(mxConstants.STYLE_VERTICAL_ALIGN, mxConstants.ALIGN_TOP);
		style6.put(mxConstants.STYLE_FONTSTYLE, mxConstants.FONT_BOLD);
		style6.put(mxConstants.STYLE_OPACITY, 100);
		style6.put(mxConstants.STYLE_FILLCOLOR, "#f7da77");
		style6.put(mxConstants.STYLE_FONTCOLOR, "#000000");
		style6.put(mxConstants.STYLE_FONTSIZE, 13);
		styleSheet.putCellStyle("SEL_TABLE", style6);

		// Style for selected primary keys
		final Map<String, Object> style7 = new Hashtable<String, Object>();
		style7.put(mxConstants.STYLE_SHAPE, mxConstants.SHAPE_RECTANGLE);
		style7.put(mxConstants.STYLE_ALIGN, mxConstants.ALIGN_LEFT);
		style7.put(mxConstants.STYLE_FONTSTYLE, mxConstants.FONT_UNDERLINE);
		style7.put(mxConstants.STYLE_FONTSIZE, 13);
		style7.put(mxConstants.STYLE_FILLCOLOR, "#f7da77");
		styleSheet.putCellStyle("SEL_PK", style7);

		// Style for selected foreign key edges
		final Map<String, Object> style8 = new Hashtable<String, Object>();
		style8.put(mxConstants.STYLE_DIRECTION, mxConstants.DIRECTION_EAST);
		style8.put(mxConstants.STYLE_EDGE, mxConstants.EDGESTYLE_ELBOW);
		style8.put(mxConstants.STYLE_ROUNDED, "true");
		style8.put(mxConstants.STYLE_ENDARROW, mxConstants.ARROW_BLOCK);
		style8.put(mxConstants.STYLE_FONTCOLOR, "#0068E0");
		style8.put(mxConstants.STYLE_LABEL_BACKGROUNDCOLOR, "#f7da77");
		style8.put(mxConstants.STYLE_LABEL_BORDERCOLOR, "#111111");
		style8.put(mxConstants.STYLE_STROKECOLOR, "#333333");
		styleSheet.putCellStyle("SEL_FK", style8);
	}

	@Override
	public boolean isCellMovable(final Object arg0) {
		final mxCell cell = (mxCell) arg0;
		boolean result = false;

		if (cell.isVertex() && cell.getParent() == getDefaultParent()) {
			result = true;
		}

		return result;
	}

	@Override
	public String getToolTipForCell(Object arg0) {
		if (arg0 instanceof ISqlForeignKey || arg0 instanceof ISqlColumn) {
			return arg0.toString();
		} else {
			return null;
		}
	}

}
